Skip to main content

Full text of "BSTJ 45: 6. July-August 1966: The SNOBOL3 Programming Language. (Farber, D.J.; Griswold, R.E.; Polonsky, I.P.)"

See other formats


The SN0B0L3 Programming Language 

By D. J. FARBER, R. E. GRISWOLD and I. P. POLONSKY 

(Manuscript received March 4, 1966) 

SNOBOL3 is a programming language designed for the manipulation 
of strings. Features of the language include symbolic naming of strings and 
pattern matching. In addition to a basic set of primitive string-valued 
functions, the system includes the facility for defining functions. These 
defined functions facilitate the programming of recursive procedures. 

This paper presents an intuitive description of SNOBOL3 and at the 
same time incorporates complete reference material for the programmer. 
The implementation of SNOBOL3 for the IBM 7094 computer operating 
under BE-SYS-7 is the basis for this description, but most of the material 
is common to all implementations. 

I. INTRODUCTION 

In recent years a number of high-level programming languages have 
been developed to extend the usefulness of the computer in dealing 
with primarily nonnumerical problems. The most widely used languages 
have been IPL, 1 LISP, 2 and COMIT. 3 In 1902 SNOBOL 4 was developed 
for problems involving the manipulation of character strings. The basic 
operations of SNOBOL permit the formation, examination, and rear- 
rangement of strings. SNOBOL3 is a generalization and extension of 
SNOBOL. New features include string-valued functions and input- 
output facilities integrated into the string structure of the language. 
There are two types of functions: primitive functions that are included 
in the system and defined functions that are defined by the programmer 
in the SNOBOL3 language. 

This paper is a description of SNOBOL3 as a programming language. 
Emphasis is placed on the language as distinct from its implementation. 
In order to provide information for the potential programmer, however, 
some references to the implementation are necessary. There are several 
implementations of SNOBOL3 which differ in detail, particularly with 
regard to input-output. The implementation for the IBM 7094 computer 
operating under the BE-SYS-7 monitor is the basis for this paper. 

895 



896 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

Areas where other implementations are likely to differ are noted in the 
applicable sections. 

Section II describes briefly and informally the essential features of 
the language. This section is designed as a survey to provide an under- 
standing of the general nature and capabilities of the language. Section 
III is an elaboration of Section II completing the description of the 
language. Sections II and III together provide a reference source for 
the programmer. Section IV describes the environment in which the 
language operates, including information which the programmer will 
find useful in running programs. A list of primitive functions and sample 
programs are included in appendices. 

II. INFORMAL DESCRIPTION 

SNOBOL3 has just one type of basic data structure: a string of 
characters. The primitive operations of the language provide for the 
formation, examination and rearrangement of strings. Arithmetic is 
defined for operands that are integer strings. The operations to be per- 
formed are specified in statements that may also be labeled and may have 
go-to's specifying transfers. A SNOBOL3 program consists of a sequence 
of statements terminated by an END statement. 

2.1 Names 

A symbolic name can be assigned to a string and used as a means of 
referring to that string. There are several ways in which a name can 
be assigned a value. The simplest is the assignment statement. For 
example, the statement 

VOWELS = "AEIOU" 

assigns the string AEIOU as the value of the name VOWELS. The 
string consisting of a pair of quotation marks enclosing a string of 
characters is a literal specifying the string AEIOU. The string VOWELS 
appearing to the left of the equal sign is a name. A name that has been 
assigned a value can be used whenever it is necessary to refer to that 
value. Thus, 

NON.CONST = VOWELS 

causes NON.CONST to have the same value as VOWELS. The null 
string, having length zero, can be assigned explicitly as value as in the 
statement 

ZIP = 



SKOBOL3 897 



2.2 Concatenation 



The basic operation of concatenation of strings is indicated by listing 
the names successively. The names are separated by blanks. Thus, to 
concatenate two string names STRING1 and STRING2 and then 
assign the result to the name STRING3, the following assignment state- 
ment suffices: 

STRING3 = STRING1 STRING2 

Many strings can be concatenated in a string expression, with literals 
as well as names used to specify the strings. Thus, the following rules 

ARGUMENT = "2X + 3" 
EXPRESSION = "SIN(" ARGUMENT ")" 

would assign the string SIN(2X + 3) to the name EXPRESSION. 

2.3 Integer Arithmetic 

Arithmetic operations can be performed on integer strings with the 
operators +, — , /,* having their usual meaning in integer arithmetic 
and ** indicating exponentiation. Blanks are used to separate the 
strings and operators. The statements 

J = "5" 

I = "3" 

N = I + "2" 

M = (I * "3") + J 

assign the values 5 and 14 to the names N and M. All arithmetic opera- 
tions are binary but more complex expressions can be constructed using 
parentheses as indicated in the last example. Arithmetic has precedence 
over concatenation, and both types of operations can be performed in 
one assignment statement. Hence, the statement 

INDEX = "A." I + "1" "." J 

assigns the value A.4.5 to the name INDEX. 

2.4 Pattern Matching 

String pattern matching consists of examining a string for a succession 
of substrings of specified form. A pattern -matching statement consists 
of the string to be examined followed by a pattern. In its simplest form 
the pattern may be simply a string. For example, the statement 

NAME.l "IS" 



898 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 19G6 

would examine the value of NAME.l to determine whether it contains 
the literal substring IS. The success or failure of a pattern match can 
affect the flow of the program and has other consequences that will be 
described later. In the example above, NAME.l, which specifies the 
string to be examined, is called the string reference of the statement. 
The string reference can also be a literal as in the following pattern- 
matching statement. 

"+-*/" OPERATOR 

There are a variety of types of patterns in SNOBOL3 enabling the 
programmer to make complex inquiries about a string. The pattern, 
for example, may be expressed as a concatenation of strings as in the 
statement 

EXPRESSION "X" OPERATOR "1" 

Patterns of greater generality may be obtained by using string varia- 
bles. As the name indicates, a string variable may have a string as value. 
There are several types of string variables and the strings which are 
acceptable values of a string variable depend on the type of the variable. 
The simplest type of string variable is the arbitrary string variable, 
so named because it can have any string as its value. An arbitrary 
string variable is designated by a name bounded by asterisks. 

A typical example of the use of an arbitrary string variable would 
be in determining whether the value of NAME.l contains the string 
THE and the string IS but not necessarily consecutively. The arbitrary 
string variable would be used to match the substring between THE and 
IS. The pattern-matching statement could be 

NAME.l "THE" *SEPARATOR* "IS" 

If the value of NAME.l were THERAPIST, then the pattern match 
would be successful with *SEPARATOR* matching RAP. 

A consequence of the successful pattern match is the naming of sub- 
strings that match string variables. In the above example, SEPARATOR 
would be given the value RAP as if the assignment statement 

SEPARATOR - "RAP" 

had been executed. 

In addition to arbitrary string variables, there are two other types of 
string variables: fixed-length and balanced. 

A fixed-length string variable can match any string of a specified num- 
ber of characters. The notation for a fixed-length variable is similar to 



SN0B0L3 899 

an arbitrary string variable, except the name is followed by a slash 
and then by a string specifying the length. 

The first three characters of the string named TEXT could be named 
PARTI by the rule 

TEXT *PARTl/"3" * 

If N had the value 3, the statement could have been written 

TEXT *PART1/N* 

As a second example, consider the statement 

« + _*» *PLUS/"1"* *MINUS/"1"* *STAR/"1"* 

The pattern successfully matches the string, and PLUS, MINUS, 
and STAR are assigned values. 

A balanced string variable can only match strings that are parenthesis 
balanced in the usual algebraic sense. Strings matched by balanced 
string variables do not have to contain parentheses but cannot be null. 
Such variables are therefore useful for pattern matching on strings that 
are mathematical expressions. The notation for a balanced string varia- 
ble consists of a name enclosed within parentheses and surrounded by 
a pair of asterisks. For example, if EXPRESSION has the value 
SIN(A*(B + C)), then the pattern match in the statement 

EXPRESSION "SIN(" *(ARG)* ")" 

is successful and ARG is given the value A*(B + C). This use of the 
balanced string variable may be compared to the arbitrary string varia- 
ble in the following example 

EXPRESSION "SIN(" *ARG1* ")" 

where the value A*(B + C would be assigned to ARG1. 

2.5 Rearranging Strings 

By combining the operations of scanning and assignment in the same 
rule, strings may be modified by replacement, deletion, or rearrange- 
ment. In particular, if a pattern is followed by an equal sign and then 
by a string expression, the substring matching the pattern will be 
replaced by the value of the expression if the pattern match succeeds. 
As an example of replacement, consider the following sequence of rules. 

CARD = "KING OF HEARTS" 
CARD "HEART" = "DIAMOND" 



900 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

The second statement causes HEART to be replaced by DIAMOND 
producing the string KING OF DIAMONDS. The following example 
illustrates how the naming of substrings by string variables may be 
used in the expression that specifies the rearrangement. The statements 

SUM = "A1+A2" 

SUM *X* "+" *Y* = "+(" X "," Y ")" 

change the value of SUM to + (A1,A2). 

2.6 Indirect Referencing 

A level of indirectness can be introduced in SNOBOL3 by prefixing 
a $ to a name. Thus, if DAY has the value TUESDAY, $DAY is equiva- 
lent to TUESDAY. An example of the usefulness of this facility is the 
ability to modify the naming done in a pattern match. Thus, in the 
following statements 

DAY = "TUESDAY" 

TEXT "," *$DAY* "," 

the name TUESDAY will be assigned to a substring of TEXT if the 
value of TEXT is such that the pattern match succeeds. 

A $ can also be prefixed to a string expression that is enclosed in 
parentheses. For example, the following statements assign the value 
of WORD to one of the names LISTA, LISTB, • • • LISTZ according 
to the first character in the value. 

WORD *CH/'l"* 
SC'LIST" CH) = WORD 

Thus, if WORD has the value DALLAS, the first statement sets the 
value of CH equal to D. The parenthesized expression 

("LIST" CH) 

has the value LISTD. Hence, the effect of the $ is to make the second 
statement equivalent to 

LISTD = WORD 

2.7 Labels and the Flow of Control 

A label may be assigned to a statement for reference when controlling 
the flow of the program. The label is merely appended to the beginning 
of the statement as in 

HERE LIST = "(A,B,C,D)" 

A statement without a label must begin with a blank. 



SN0B0L3 901 

Statements in a SNOBOL3 program are executed in sequential order. 
This order of execution can be modified by means of a go-to appended 
to the end of a statement. Go-to's are separated from the rest of the 
statement by a slash. There are two types of go-to: unconditional and 
conditional. The unconditional go-to consists of a label enclosed within 
parentheses. Thus, after executing 

HERE LIST = "(A,B,C,D)" /(THERE) 

control is transferred to the statement with label THERE. By means 
of the conditional go-to, control can be transferred depending on whether 
success or failure has been signaled during the execution of the statement. 
The letters S and F are used to indicate the two conditions. For example, 
in the following rule the transfer to the statement with label L2 will 
occur only if the pattern match is successful. 

LI TEXT "," *A* "." /S(L2) 

If the pattern match fails, the next statement in the program is executed. 
Transfer on a failure signal can be similarly programmed. As an ex- 
ample, consider the following sequence of statements which will delete 
from the string named TEXT all occurrences of the characters in LIST: 

LI LIST *CHAR/"1"* = /F(DONE) 

L2 TEXT CHAR = /S(L2)F(L1) 

DONE 

In statement LI, the first character in LIST is named CHAR and is 
deleted by replacing it with a null string. Statement L2 is executed 
repeatedly until all occurrences of CHAR have been deleted from TEXT. 
Then the process iterates using the next character in LIST. Finally, 
when there are no characters left in LIST, the pattern match in state- 
ment LI fails. Thus, if TEXT had the value A+B*C/D+E and 
LIST the value +*/-, the resulting value of TEXT would be ABCDE. 
A transfer may be computed by the use of indirectness in the go-to 
as illustrated in the following example: If PDL is assumed to have the 
value A1,B5,C3, then the statement 

PDL *RET* "," = /S($RET) 

causes deletion of Al, and transfer to the statement labeled Al. 

2.8 Functions 

There are two types of functions in SNOBOL3: primitive and defined. 
Some functions may signal failure. This failure terminates the execution 



902 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

of the statement in which the function call occurs and may be used to 
control the flow of the program. 

2.8.1 Primitive Functions 

A basic set of primitive functions, programmed at the machine-lan- 
guage level, has been included in the SNOBOL3 system. 

SIZE is an example of a primitive function. The value of SIZE(X) 
is the number of characters in the string named X. Thus, the statements 

STR = "FOUL" 
Z = SIZE(STR) 

assign the value 4 to Z. As a result of the statements 

X - SIZE(TEXT) - "1" 

TEXT *FRONT/X* *LAST* 

LAST is defined to be the name of the last character in TEXT. 

One use of functions is to conditionally signal failure and hence alter 
the flow of control. For example, EQUALS(X,Y) signals failure if X 
and Y do not have identical values. If the values of X and Y are identi- 
cal, the function returns the null string as value. Thus, the statement 

N - EQUALS(A,B) N 4- "1" 

will increment N only if the values of A and B are equal. 

Another type of primitive function is one that modifies the behavior 
of the SNOBOL3 system itself. The function call MODE("ANCHOR") 
is an example. It modifies the pattern matching processor and returns 
a null value. Subsequently a pattern match can succeed only if the 
matching substring is at the beginning of the string reference. Thus, if 
MODE(" ANCHOR") has been executed before the statements 

EXP = "SIN(A + B)" 
EXP"(" *(ARG)* ")" 

the pattern match fails. 

2.8.2 Defined Functions 

A section of SNOBOL3 program can be defined to be a function and 
certain names occurring in the section can be declared formal parameters. 
This function declaration is accomplished by a call of the primitive 
function DEFINE. For example, 

DEFINE("REVERSE(X)","REV") 



SN0B0L3 903 

declares the section of program beginning at the statement with label 
REV to be a function named REVERSE with a formal parameter X. 
Suppose REVERSE(X) returns as value the string named X with 
the characters reversed. Then the portion of program denning RE- 
VERSE could be 

REV X *CHAR/'T'* = /F(RETURN) 

REVERSE = CHAR REVERSE /(REV) 

The reserved label RETURN causes return to the place at which the 
function was called. The name of the function, in this case REVERSE, 
serves a special purpose. When the function is called, its value is saved 
and then set to the null string. When transfer to RETURN occurs, 
its value is the value returned by the function. Thus, 

Z = REVERSEC'ABCDE") 
assigns the value EDCBA to Z. 

2.9 Statement Format 

A SNOBOL3 statement has a simple format consisting of several 
fields of arbitrary length separated by blanks. The fields are the label, 
string reference, pattern, equal sign, replacement expression, and the 
go-to. A statement may contain some or all of these fields. The replace- 
ment statement 

HERE TEXT " " *WORD* " " = " " /S(GOT) 

has all of the fields. 

If the label is omitted the statement must begin with a blank. If 
the next field is not a go-to, it is considered to be the string reference. 
Thus, 

/(L7.3) 
THERE /(HERE) 

are statements that do not have a string reference. The statement 

L5 EQUALS(OP,"END") /S(END) 

has the string reference EQUALS(OP,"END"). 

The field following the string reference up to an equal sign or a go-to 
is the pattern. In a statement without a go-to or equal sign, the pattern 
is the field following the string reference. Thus, in each of the following 
statements 



904 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 





STR 


A 


*B* V = B 


/S (GREAT) 




STR 


A 


*B* "," = 




LI 


STR 


A 


*B* "," 


/S(GREAT) 




STR 


A 


*B* "," 




the pattern is 











A *B* "," 

Note that the elements within the pattern are also separated by blanks. 
A statement without a pattern, but containing an equal sign, is an 
assignment statement. Some examples are: 

ANS = N + "5" 

RES = /(READ) 

The latter example assigns the null string as the value of RES. 
No fields are permitted after the go-to field. 

m. DETAILED DESCRIPTION 

The previous section was an informal description of the basic parts 
of SNOBOL3. The following section completes this description in a 
more comprehensive and detailed manner. 

3.1 Names and String Expressions 

3.1.1 Names 

Names are used to refer to string values symbolically. In addition, 
names are required for certain parts of statements: 
(i) string variable names 
(ii) string references in assignment statements 
(Hi) labels in go-to fields. 

Names may be explicit or implicit. Explicit names can consist only 
of letters, numbers, periods and colons. Examples are: 

N 

STATEMENT . VARIABLE 

X:l 

37 

Implicit names, constructed by indirect references, may consist of any 
nonnull string of characters. Any indirect reference is an implicit name. 



SN0B0L3 905 

For example: 

$F 

SSIZE(N) 
$("M" K) 

Consequently, 

= "6" 

is syntactically incorrect, but 

INAME =",,,," 
$INAME = "6" 

is proper. 

The particular characters comprising a name have no significance; 
a name is merely an identifier. A name may be the same as a label or 
the name of a function. 

3.1.2 String Expressions 

The basic string-valued elements are: 
(i) literals 

(ii) names 

(Hi) function calls 

(iv) arithmetic operations 
(v) parenthetical groupings. 
Any string of characters (including the null string) not containing a 
quotation mark (see Section 3.1.3) may be included between the quo- 
tation marks of a literal. Function calls, parenthetical groupings, and 
names may be indirectly referenced. Parentheses are required between 
successive levels of indirect references. 

A string expression is a string-valued element or the concatenation 
of several such elements. Some typical string expressions are: 

"PARAGRAPH SUB-HEADINGS FOLLOW" 

"N" ((A + "1") * INTERVAL) 

$BASE + SIZE(N) 

F(X,F(X,X)) 

S(S(SROOT)) 

M"."P 

$("N" I) 



906 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 1<J(>6 

3.1.3 Names and Values 

All names have null values at the beginning of program execution 
except for the string QUOTE. QUOTE has a preassigned value which 
is a quotation mark. 

Names, including QUOTE, may subsequently be given other values 
by assignment statements or as a result of pattern matching. The re- 
sulting name-value relationship between strings forms the basic data 
structure in SNOBOL3. Structures can be built to arbitrary depths. 
For example, the statements 

Nl = "N2" 
N3 = "N2" 
N2 = "N4" 
N4 = "N6" 
N5 = "N4" 
N6 = "N3" 

might be used to represent relationships between data as indicated in 
Fig. 1. 

Indirect referencing can be used to refer to the relationships in the 
structure. The range of such structures is limited by the fact that a 
name can have at most one value at any time, while a string can be the 
value of any number of names simultaneously. 

3.2 Arithmetic 



3.2.1 Integers 

Some strings have the property of being SNOBOL3 integers. Such 
strings are required in arithmetic operations and as arguments of certain 
primitive functions. In order for a string to be a SNOBOL3 integer 




N6 
Fig. 1 — The name-value relationship among data. 



SXOBOL3 907 

(i) it must consist entirely of digits except for the first character 

which may be a sign, and 
(ii) its absolute value considered as a decimal integer must be less 
than 10 10 . 
In numerical contexts 

(i) unsigned numbers are taken to be positive, 
(ii) leading zeros are ignored, 
(Hi) minus zero is equal to plus zero, and 
(iv) the null string is taken to be zero. 
The following strings are SNOBOL3 integers: 

5 

+ 10 

0003976 

-37 

-000003 

+0 

The following strings are not SNOBOL3 integers: 

+A 

3.27E-2 

3.7 

876935476271 

0- 

10,000 

The primitive function .NUM(X) succeeds, returning a null value, if 
the value of X is a SNOBOL3 integer and fails otherwise. Thus, 
.NUM("A") fails, while .NUM("100") returns a null value. 

3.2.2 Arithmetic. Expressions 

Arithmetic operations must be separated from their operands by 
blanks. Consequently A+B is syntactically incorrect. Any expression 
whose value is a SNOBOL3 integer is an acceptable operand. 

All arithmetic operations are binary. Thus, 

N + "3" 
is a legal operation, while 

V _|_ "3" * "9" 



908 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

is a syntactic error. Parentheses may be used for grouping terms to create 
more complicated expressions: 

N + ("3" * "2") 

In expressions containing both concatenation and arithmetic, arithmetic 
has precedence over concatenation. Thus, the value of 

"JJ" "5" -1- tC7f> 

is N12 and the value of 

<<o»» * "O" "10" / "2" 

is 65. Parentheses may be used to group concatenations and arithmetic 
to obtain the desired result. Thus, the value of 

"3" * ("2" "10" / "2") 

is 75. 

The following sequence of statements illustrates possible combina- 
tions: 

ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 

N = SIZE(ALPHA) + "1" 

M = (N + SIZE(N)) * "2" 

K = ("-" N M) + "5" 

As a result of executing these statements, N would have the value 27, 
M the value 58, and K the value —2753. 

The result of an arithmetic expression is a normalized SNOBOL3 
integer. Integers are normalized as follows : 
(i) positive integers are unsigned, 
(ii) leading zeros are removed, and 

(mi) any value equal to zero is returned as an unsigned zero. 
Thus, 

"+0003" + "0" 

has value 3, and 



tin * iioii 



has the value 0. 

3.2.3 The Evaluation of Arithmetic Expressions 

Two modes for evaluating arithmetic expressions are available. The 
normal mode is truncation. In the truncation mode any fractional part 



SNOBOL3 909 

resulting from division (or exponentiation) is discarded. Thus, the value 
of 



is 2, and the value of 



"5" / "2" 



<<Q>) ** ti 1 >> 



-1' 



isO. 

An integer mode is available which causes an arithmetic operation to 
fail if a fractional part would result. The integer mode may be invoked 
by executing the function call MODE("INTEGER"). The normal 
mode may be restored by executing MODE("TRUNCATION"). 

3.2.4 Error Conditions in Arithmetic Operations 

Error conditions in arithmetic operations occur if : 
(i) a fractional part would occur in integer mode, 
(ti) an operand is not a SNOBOL3 integer, 
(Hi) the result of an arithmetic operation is not a SNOBOL3 integer 

(because it is too large) , or 
(iv) division by zero is attempted. 
In all cases, the arithmetic operation fails, terminating the execution of 
the rule in which it occurs. The failure may be utilized to change the flow 
of control by means of a conditional go-to. 

3.2.5 Numerical Functions 

There are she functions for comparing the magnitude of integers: 

.EQ(X,Y) (X = Y) 

.NE(X,Y) (X ^ Y) 

.LT(X,Y) (X < Y) 

.LE(X,Y) (X ^ Y) 

.GT(X,Y) (X > Y) 

.GE(X,Y) (X ^ Y). 

These functions succeed, returning a null value, if the condition indi- 
cated is satisfied and fail otherwise. The functions also fail if either 
argument is not a SNOBOL3 integer. A common use of the functions is 
to control loops. For example, the following program assigns the squares 
of the first 100 positive integers to the names SQ1 through SQ100, 
respectively. 



910 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 
N = "1" 

COMPUTE $("SQ" N) = N * N 

N = .LT(N,"100") N + "1" /S(COMPUTE) 

The function .REMDR(X,Y) has as its value the remainder of X 
divided by Y. For example, the value of 

.REMDR("5", "2") 

is 1. The sign of the remainder is the same as the sign of the divisor and 
the value is normalized. 

.REMDR fails if either argument is not a SNOBOL3 integer or if 
the value of Y is zero. 

3.3 Pattern Matching 

Pattern matching is a basic operation in SNOBOL3. The examina- 
tion, rearrangement, and combination of data depend on pattern 
matching; and the success or failure of matching is often used for alter- 
ing the flow of control. 

3.3.1 Pattern Elements 

A pattern consists of a succession of pattern elements separated by 
blanks. There are two basic categories of pattern elements: string con- 
stants and string variables. 

Any string expression is a constant, except that arithmetic expressions 
must be enclosed in parentheses. The following expressions are examples 
of string constants : 

K 
"35R" 

SIZE(Z) 

.LE(N,M + SIZE(L)) 

(M + (N * "2")) 

String variables may or may not have associated names. The follow- 
ing elements are examples of string variables: 

** 

*()* 
*/«3»* 

♦VARIABLE 1* 

*$SIZE(N)* 
*(EXP)* 



SNOBOL3 911 

The length of a fixed-length variable may be any string constant 
whose value is a nonnegative SNOBOL3 integer when evaluated. The 
following fixed-length variables illustrate possible forms the length 
may take: 

*FL/N* 

*V/(SIZE(N) + "1")* 
*V/(M + (N *Z))* 

The lengths of the following variables are syntactically incorrect: 

*HEAD/N + "1"* (Arithmetic expressions must be enclosed 

in parentheses.) 
*SPAN/"A"* (The value of the length must be an integer.) 

3.3.2 The Matching Process 

Pattern matching consists of three phases : 
(i) evaluation of expressions in the pattern, 
(ii) the actual matching, and 

(Hi) the assignment of values to names associated with string varia- 
bles. 

3.3.2.1 Evaluation. Before any matching, all expressions in the pattern 
are evaluated. Expressions may occur in string constants, the names of 
string variables, and in the length of fixed-length variables. Evaluation 
proceeds from left to right. Any failure in evaluation (such as the failure 
of a function call or arithmetic operation) terminates the execution of 
the rule without any matching or naming. 

The value of all expressions is fixed by evaluation before matching. 
No evaluation is performed during matching. The only exception to this 
rule is back referencing described in a following section. Thus, in the 
pattern 

*N* *SPAN/N* 

the length of the fixed-length variable is the value of N before matching 
and is not influenced by any subsequent match for the arbitrary string 
variable with the name N. 

3.3.2.2 Matching. Pattern elements must match consecutive substrings 
in the value of the string reference. In most cases the match can easily 
be determined from the following rule: 

Pattern matching proceeds from left to right, each pattern element 
matching the shortest possible substring according to the type of the 
element. 



912 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 19GG 

In some complicated cases, more precise definitions are necessary. The 

following definitions provide the details for resolving difficult cases. 

(i) The pattern match proceeds element by element from left to 

right starting at the leftmost (first) element. The elements must 

match consecutive substrings in the value of the string reference. 

(it) An attempt is first made to match the first element starting at 

the first character in the value of the string reference. If this is 

not possible, an attempt is made starting at the second character, 

and so on. 

(Hi) When an element is successfully matched, a forward match is 

attempted for the next element. 
(iv) If an element cannot be matched, rematch is attempted for the 
preceding element. Rematching is an attempt to extend the sub- 
string matching a pattern element and occurs because the pat- 
tern match cannot be successfully concluded with the previous 
match. 
(v) Pattern matching terminates successfully when the rightmost 
(last) pattern element has been matched. Pattern matching 
terminates in failure if no match can be found for the first ele- 
ment. 
The methods of forward matching and rematching depend on the type 
of the pattern element. In each case, the element must match a substring 
in the string reference starting at the character following the substring 
matching the preceding element. The details follow. 

(a) String Constants 

In forward matching, a string constant matches a substring identical 
to its value. If this is not possible, forward matching fails. A null con- 
stant always matches. 

No rematch is possible, and rematching always fails. 

See the special case of back referencing. 

(b) Arbitrary String Variables 

In forward matching, an arbitrary variable matches a null string. 

In rematching, one character is added to the substring previously 
matched by the variable. If the string reference is not long enough for 
such a match, rematching fails. 

As a special case, if the last element in the pattern is an arbitrary string 
variable, it matches the remainder of the string. 



SN0B0L3 913 

(c) Balanced String Variables 

In forward matching, the string matched by a balanced variable 
depends on the first character of the substring where the variable is to 
match. If this first character is not a parenthesis, then the variable 
matches that character. If the first character is a right parenthesis, the 
match fails. If the first character is a left parenthesis, the string being 
examined is considered character by character until a matching right 
parenthesis is found. If there is no matching parenthesis, failure is indi- 
cated. Notice that a balanced string variable always matches at least one 
character. 

In rematching, the previously matched substring is extended by the 
next shortest balanced string according to the rules for forward matching. 
If this is not possible, rematching fails. 

(d) Fixed-Length String Variables 

In forward matching, a fixed-length variable matches a substring of 
length specified by the variable. If the string being examined is not 
long enough, forward matching fails. 

Rematching always fails. 

(e) Back Referencing 

Back referencing is a special case in pattern matching in which tenta- 
tively matched substrings can be referred to dynamically during the 
matching process. If a constant in the pattern has the same name as a 
name associated with a variable to the left of it in the pattern, the value 
of the constant is taken to be the substring currently matched by the 
variable. Thus, in the pattern 

*N* "," N 

the constant N must match a substring identical to the substring match- 
ing *N*. Since matching is done left to right, a tentative match always 
exists for a back-referenced variable. 

Back referencing only occurs when the name associated with a varia- 
ble is to the left of a constant with the same name. Consequently the 
pattern 

N «» * N * 

does not contain back referencing. 

If there are several occurrences of the same name in a pattern, a 



914 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

named constant back references the variable with its name which is 
nearest to it on the left. In the pattern 

*N* " " N N *N* " " N 

the first and second named constants refer to the first variable and the 
third named constant refers to the second variable. 

Any type of variable may be back referenced and any number of 
named constants may back reference variables in an arbitrarily compli- 
cated way. 

The determination of back referencing within a pattern is made after 
the evaluation of expressions in the pattern but before matching. In 
the statements 

A = "C" 

B *C* "," $A 

the pattern is back referenced. However, in the statements 

VARI = "SPAN" 
X *VARI* $VARI 

there is no back referencing. 

Back referencing only applies to names which are pattern elements 
and not to any other name in the pattern. Specifically in the pattern 

*N* *INT/SIZE(N)* 

the length of INT is determined by evaluation before matching and 
does not change during the matching process. 

3.3.2.3 Naming. If the pattern match fails, no naming is done and 
the execution of the rule is terminated. If the pattern match succeeds, 
naming is performed from left to right for each name associated with a 
string variable. The substring matching the variable becomes the new 
value of the associated name. If a name is associated with more than one 
variable, the value is assigned corresponding to the rightmost variable 
with that associated name. 

In the case that a name is computed as the result of an expression, the 
name is determined by the evaluation made before pattern matching. 
Thus, in the statements 

A = "C" 

Z *A* "," *$A* 

the name associated with the second string variable is C regardless of 
the value of Z. 



SN0BOL3 915 

3.3.3 Pattern Matching Modes 

In the normal mode of pattern matching, the first element of the pat- 
tern may match starting anywhere in the value of the string reference. 
Thus, the simple match 

"0123456789" "6" 

succeeds. This mode is referred to as unanchored. The alternative mode, 
in which the first pattern element must match a substring beginning 
with the first character of the string reference, is called anchored. This 
mode may be invoked by executing the function call 

MODE(" ANCHOR") 

Subsequently, all pattern matching will be in the anchored mode unless 
otherwise modified. The normal mode may be restored by 

MODE("UNANCHOR") 

The mode of matching may be changed for the duration of a single 
statement by means of the two functions ANCHOR and UNANCH. 
These functions, which have no arguments, must be called before match- 
ing (Refer to the Section 3.4.3). Both functions return null values. Thus, 

in 

Z ANCHOR( ) "." *IDENT* "." 

the pattern match is anchored regardless of the matching mode current 
in the program. Subsequent statements are not affected. The null 
value returned by ANCHOR does not affect the match since a null 
string may match anywhere. 

ANCHOR and UNANCH supersede the MODE function even if 
the MODE function is executed subsequently in the evaluation of the 
pattern elements. Hence in the statement 

STRING UNANCH( ) MODE("ANCHOR") 

the pattern match is unanchored, although the anchored mode will 
subsequently prevail. 

3.3.4 Examples of Pattern Matching 

The following examples illustrate some of the situations which occur 
in pattern matching. String reference values are given as literals for 
clarity. Naming is indicated for those pattern matches which succeed. 
The normal unanchored matching mode is assumed. 



916 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

Example 1: 

"K)AK(A + B + QST" "K" *(A)* "ST" 
The match succeeds with 

A = "(A + B + C)" 

Example 2: 

"K)AK(A + B + C)ST" ANCHOR( ) "K" *(A)* "ST" 

The match fails. 

Example 3: 

"S)(S + A*B(S" "S" *(A)* "S" 
The match fails. 

Example 4-' 

"ABCDEFGHIJKLMNO" *HV/"5"* *A* "K" *B* 

The match succeeds with 

HV = "ABCDE" 
A = "FGHIJ" 
B = "LMNO" 

Notice that since the last pattern element is an arbitrary string variable 
it matches the remainder of the string reference. 

Example 5: 

«364 : » *a* *SUM/"3"* ":" 

The match succeeds with 

A = " » 

SUM = "364" 

Example 6: 

"ARMY" *A* *B* *C* 

The match succeeds with 

A - " " 
B - " " 
C = "ARMY" 



SNOBOL3 917 

Notice that the first two arbitrary string variables match null strings 
since this satisfies the requirement for matching the shortest possible 
substrings. 

Example 7: 

"ABC" *(BAL1)* *(BAL2)* 

The match succeeds with 

BALI = "A" 
BAL2 = "B" 

Example 8: 

"AB" *(BAL1)* *(BAL2)* *(BAL3)* 

The match fails since each balanced string variable must match at least 
one character. 

Example 9: 

"ABCD" *s/"2"* *t/"3"* 
The match fails since the string being matched is not long enough. 

Example 10: 

"ABCDEFGHFGH" *A/"3"* A 

The match succeeds with 

A = "FGH" 
This is a simple example of back referencing. 

Example 11: 

"ABCDEFGHFGH" ANCHOR( ) *A/"3"* A 
The match fails. 

Exam-pie 12: 

"32579.97" *A* *B* "." B A 

The match succeeds with 

A = "7" 
B = "9" 



918 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

These values can be verified by carefully applying the matching rules. 
(The expected match might be a null value for both A and B.) 

Example 13: 

The following example illustrates the complexity which may occur 
with back referencing. 

"BACCABACABABACACAB" *A* *(B)* *(C)* 

*D* C D B D C A *E* A E 

The match succeeds with 



A 


= 


(( j; 


B 


= 


"BAC" 


C 


= 


"CAB" 


D 


= 


"A" 


E 


= 


<< » 



Example 14-' 

"A,A,B,B" *X* "," X "," *X* "," X 



The match succeeds with 



X = "B" 



3.4 Program Structure and the Flow of Control 

A program consists of a succession of statements terminated by an 
END statement containing the reserved label END. The END state- 
ment may also contain a name which is the label of the first statement 
to be executed. If the END statement contains no name, execution 
begins with the first statement of the program. 

Statements are subsequently executed one after another unless con- 
trol is transferred by means of a go-to. 

3.4.1 Labels 

Labels are distinguished by beginning in Column 1. A statement with 
no label must have a blank hi Column 1. The first character of a label 
must be a letter or a digit. Subsequent characters may be anything but 
blanks. Labels are program constants; the particular characters in a 
label have no significance even if they resemble some other structure 
such as a name or a function call. Thus F(X) is a legitimate label but 
has no further meaning. 



SNOBOL3 919 



3.4.2 The Go-To Field 



Go-to's are used to alter the ordinary sequential execution of state- 
ments. In general, a statement may be successfully completed, or failure 
may be indicated for a number of causes. The success or failure may be 
sensed and used by corresponding conditional go-to's to alter the order 
in which statements are executed. 

A statement with an unconditional go-to may not have conditional 
go-to's. Furthermore, a statement may not have more than one uncondi- 
tional, success or failure go-to. In statements with both success and 
failure go-to's, the go-to's may occur in either order. 

The labels given in the go-to's must be names and transfer is made to 
the name (not its value). The label in a go-to may be computed by the 
use of implicit names resulting from indirect references. For example, 
in the statement 

X = "3" /($("R" X)) 

transfer is made to the statement with label R3. Function calls occurring 
in go-to's must not fail. 

3.4.3 The Order of Execution Within a Statement 

The order of execution of operations within a statement may be 
important to the programmer for two reasons: 

(i) Failure of an operation within a statement terminates execution 
of the statement at that point so that subsequent operations are 
not performed. 
(ii) Calls of defined functions may change the values of names which 

appear subsequently in the same statement. 
Consequently, a detailed knowledge of when various parts of a state- 
ment are evaluated may be required to determine how a program will 
function. The overall order of execution within a statement is as follows: 
(i) The string reference (if any) is evaluated. 
(ii) The elements of the pattern (if any) are evaluated from left 

to right (see Section 3.3.2). 
(m) The pattern match (if any) is performed. 
(iv) Any naming as the result of a successful pattern match is 

performed. 
(?•) If a string expression is specified as a replacement, that string 

expression is evaluated. 
(vi) Reformation (if specified) of the value of the string reference 
is made. 



920 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

(pit) The go-to (if any) corresponding to the success or failure of 

the statement is evaluated. 
(piii) Transfer is made to the next statement accordingly. 
If failure is signaled in any of the steps (i) through (pi) above, execu- 
tion of the statement terminates at that point and the appropriate go-to 
is evaluated. In particular note that only the appropriate go-to is evalu- 
ated. The order of evaluation within a string expression is as follows: 
(t) Elements in a concatenation are evaluated left to right. 
(it) In a function or parenthetical grouping, the innermost expression 

in the nesting is evaluated first. 
(Hi) Arithmetic is performed before concatenation. 
(iv) All arguments of a function are evaluated, left to right, before 
the function is called. 

3.4.4 Termination of Execution 

Program execution is usually terminated by a transfer to the label 
END or by flowing into the END statement. 

Depending on the monitor system under which SNOBOL3 operates, 
the termination of a SNOBOL3 program may or may not terminate the 
job which initiated the SNOBOL3 program. Thus, two modes may be 
distinguished: 

(i) endjob, in which job execution is terminated upon completion of 
the SNOBOL3 program, and 

(it) system, in which job execution may continue after completion of 
the SNOBOL3 program. 
The normal mode in SNOBOL3 is endjob. The alternative mode may 
be invoked by the function call MODE("SYSTEM"). The normal 
mode may be restored by the function call MODE("ENDJOB") 

Execution of a SNOBOL3 program may be interrupted by the func- 
tion SYSTEM(FILE). A call of SYSTEM (FILE) suspends program 
execution, returning control to the monitor. The input source for the 
monitor is set to the value of FILE. If the value of FILE is null, the 
input source is set to the standard input source. The availability of 
SYSTEM depends on the monitor under which SNOBOL3 operates. 

3.5 Input-Output and File Manipulation 

3.5.1 Implementation Differences 

Input-output is particularly subject to differences in machines and 
monitor systems. Consequently the input-output behavior of the 



SN0B0L3 921 

SN0B0L3 system may vary considerably in different implementations. 
Reference to files, record sizes and the handling of end-of-file differ 
most. The following sections should be read with this in mind. 

3.5.2 String-Oriented Input and Output 

Input and output is accomplished through string names associated 
with logical files. 

For example, SYSPOT ("system peripheral output tape") is associ- 
ated with the standard output file. Every time SYSPOT is given a 
value, a copy of the value is printed on the system output file. Thus, 
the statement 

SYSPOT = "TABLE OF VALUES" 

will cause the printing of TABLE OF VALUES on the output listing. 

SYSPPT ("system peripheral punch tape") is associated with the 
standard punch file. Values given SYSPPT are punched rather than 
printed. 

Similarly, SYSPIT ("system peripheral input tape") is associated 
with the standard input file. Every time the value of SYSPIT is re- 
quired, a card image is read from the input file to become the value of 
SYSPIT. For example, the statement 

SYSPIT *FIELD1* "," *FIELD2* " " 

might be used to read and name data items on input cards with the 
format indicated by the pattern. 

3.5.3 The Association of String Names with Files 

The names SYSPOT, SYSPPT, and SYSPIT are automatically 
associated with standard files at the beginning of program execution. 
Any name (including these three) may be associated with any file during 
program execution by means of association functions. All the following 
functions return null values. 

(0 PRINT(NAME,FILE) associates the value of NAME with 
the value of FILE in the print sense. Thus, 

PRINT("X", "OUT") 

associates the name X with logical file OUT. After execution of 
this function call, copies of all values assigned to X will be placed 
on the file OUT. 
(it) PUNCH (NAME,FILE) associates the value of NAME with 



922 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 1000 

the value of FILE in the punch sense. The distinction between 
punch and print association is described in the next section. 

(in) READ(NAME,FILE) associates the value of NAME with 
the value of FILE in the read sense. 

The execution of an association function detaches the name from 
any file with which it may be associated. Thus, 

PUNCH("SYSPOT", "SCR") 

is permissible. 

Any nonnull name may be associated with any file. If the value of 
FILE is null, the name will be associated with the appropriate standard 
file. A name may be associated with only one file, but any number of 
names may be associated with a file. 

3.5.4 Output 

Output occurs whenever an output-associated name is given a value. 
Thus, 

FIELD *SYSPOT* "," *SYSPOT/"5"* 

results in two outputs if the pattern match is successful. 

Print and punch association differ in carriage control. When output 
is performed on values whose names are associated in the print sense, 
six blanks are prefixed to provide carriage control. No carriage control 
is provided for output resulting from punch association. Consequently, 
punch should be used for intermediate files which are to be subsequently 
read. 

Printing on the standard print file is 126 characters per line (not count- 
ing carriage control). Additional lines are generated as necessary for 
longer strings. Punching on the standard punch file is 72 characters per 
card with additional cards generated as necessary. Values punched or 
printed on other files are augmented with blanks to an even multiple 
of six characters. Resulting strings containing 84 characters or less are 
printed as single records of the length of the augmented string. Longer 
records are printed 84 characters per record. Any residual string over a 
multiple of 84 characters is printed as a record of the residual length. 

Printing a null value always produces a record because of the six 
blanks prefixed for carriage control. Punching a null value does not pro- 
duce a record. 

Since output of strings may break one string into many records, care 
must be taken that the strings may be properly reconstructed if neces- 



SNOBOL3 923 

sary. This remark also applies to padding with blanks and handling of 
null strings as described above. 

Names associated with output files retain their values like any other 
names. The output process does not destroy values. 

3.5.5 Input 

All strings read from the standard input file are 84 characters long. 
Blanks are used to fill out shorter records. Records read from other files 
are not extended. 

It is particularly important to notice that any use of the value of a 
read-associated name results in the reading of a record and the loss of 
the previous value of the name. This is true regardless of context. For 
example, 

SYSPIT *Z* 

results in the reading of a record. The record is destroyed by any sub- 
sequent use of SYSPIT. Consequently, it is good programming practice 
to assign the result of reading to some other string. For example, 

SYSPOT = SYSPIT 

prints the next record, and the resulting string remains as the value of 
SYSPOT for further use. 

An important aspect of a read-associated name is the indication of 
failure if the read operation fails (as the result of an end-of-file or binary 
record). Such a failure terminates execution of the statement in which it 
occurs and may be used by a conditional go-to. The ability of the 
SNOBOL3 system to regain control after an end-of-file depends on the 
monitor under which SNOBOL3 operates. 

3.5.6 Other Functions 

Several functions exist for performing standard input-output opera- 
tions and file manipulation. All these functions return null values. 

(i) DETACH(NAME) removes the value of NAME from any 
input-out association. For example, 

DETACH ("SYSPOT") 

terminates normal print output. If the value of NAME is not 
associated with a file, no action is taken. 
DETACH may be used to save the value of a name associated in the 
read sense. For example, the statements 



924 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

SYSPIT *A* ", M *B* "," *C* /S(PROG) 
DETACH("SYSPIT") /(ERROR) 

might be used to go to an error routine in case an input record does not 
have the expected format. By detaching SYSPIT, the record in error 
may be examined without destroying it. 

(it) REWIND (NAME) rewinds the file associated with the value 

of NAME. Note that the argument is the name and not the file. 

An end-of-file is written on a file in output status before it is 

rewound. 

(Hi) BSREC(NAME) backspaces one record on the file associated 

with the value of NAME. 
(iv) EJECT (NAME) writes an eject carriage control character on 

the file associated with the value of NAME. 
(v) OPEN(KEY,FILE) opens the specified file in the key area 
which is the value of KEY. The applicability of this function 
depends on the monitor under which SNOBOL3 operates. 

3.6 Primitive Functions 

3.6.1 Function Calls 

Function calls may occur anywhere in a statement where a string 
value is appropriate. An argument of a function may be any string 
expression, however complicated. Any argument may be explicitly null 
and trailing arguments that are omitted are given null values. Thus, 
the three function calls 

EQUALS(X," ") 

EQUALS(X,) 
EQUALS(X) 

are equivalent. A primitive function may be called with up to six argu- 
ments, regardless of the number specified by the function. Such addi- 
tional arguments are evaluated but are ignored by the function. 

All function calls return strings as value if they succeed. In the case 
of functions that have no natural value, a null string is returned. 

It is important to notice that the function name and the left paren- 
thesis may not be separated by blanks. Thus, 

SIZE(N) 

is a function call, while 

SIZE (N) 



SN0B0L3 925 

is the concatenation of a name and a parenthetical grouping. Similarly, 
functions such as ANCHOR( ) which have no argument must be written 
with the parentheses. Otherwise they will be taken for string names 
rather than function calls. 

3.6.2 Functions Relating to Functions 

(0 OPSYN(NEW,OLD) OPSYN permits the programmer to asso- 
ciate a new name with a function. Thus, for example, 

OPSYN("LENGTH","SIZE") 

makes the name LENGTH a function with the same definition as 
SIZE. Either LENGTH or SIZE may now be used to call the function. 
New names may be associated with either primitive or denned functions. 
OPSYN returns a null value. 

(it) CALL(FNC) CALL permits the programmer to invoke a func- 
tion implicitly by interpreting a string as a function call. The value of 
FNC must correspond syntactically to a function call. 

For example, the function call 

CALL("SIZE(M)") 

is equivalent to the function call 

SIZE(M). 

The arguments in FNC are interpreted as explicit names. Thus, all 
arguments in a function invoked by CALL must be assigned names. 
For example, to invoke 

.GT(SIZE(N),"5") 

by the use of CALL, statements of the form 

ARG1 = SIZE(N) 
ARG2 = "5" 
CALL(".GT(ARG1,ARG2)") 

are required. 

Any primitive or defined function may be invoked by CALL. Value 
is returned and success or failure indicated in the same manner as if the 
function call appeared explicitly. 

3.6.3 Miscellaneous Primitive Functions 

There are six primitive functions in addition to the functions described 
elsewhere in Section III. They are: 



926 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 19G6 

(i) EQUALS(X,Y) EQUALS returns a null value if the value of X 
is identical to the value of Y and fails otherwise. The values must 
be identical and not just numerically equal (compare Section 
3.2.5). 

(ii) UNEQL(X,Y) UNEQL returns a null value if the value of X 
is not identical to the value of Y and fails otherwise. 

(Hi) TRIM(S) TRIM returns as value the value of S with trailing 
blanks removed, thus, for example, TRIM(SYSPIT) is a con- 
venient method of removing superfluous blanks from input cards. 

(iv) TIME( ) TIME is a function of no arguments which returns as 
value the millisecond time from the beginning of program 
compilation. The value is returned as a 6-character number. 
(v) DATE( ) DATE is a function of no arguments which returns as 
value the current date. The value is returned as a 6-character 
number. For example, April 1, 1966 would appear as 

040166 

(vi) SIZE(S) SIZE returns as value the number of characters in the 
value of S. For example, the value of SIZE ("0123456789") is 10. 

3.6.4 Addition of Primitive Functions to the SNOBOL3 System 

The SNOBOL3 system is designed so that separately-compiled primi- 
tive functions may be added easily. This facility has been used exten- 
sively to add a wide range of capabilities. 6,6 ' 7 A discussion of the format 
and communication conventions required for primitive functions is 
beyond the scope of this paper. Ref. 8, which is available from the au- 
thors, describes these matters in detail. 

3.7 Defined Functions 

3.7.1 The Definition of a Function 

A defined function is characterized by four items: 
(i) a name, by which it is called and which is used for returning 

value, 
(it) a list of formal arguments, used for passing values to the function, 
(Hi) a label, indicating its entry point, and 
(iv) a list of local names used by the function. 
A function must be defined during program execution before it is used. 
This definition is accomplished by a call of the DEFINE function which 



SNOBOL3 927 

establishes the four items above. The form of the call is 

DEFINE(FORM,LABEL,NAMES) 

FORM is a prototype of the function call, giving the function name 
and the list of formal arguments. The value of LABEL is the entry 
point, and the value of NAMES is the list of local names separated by 
commas. For example, 

DEFINE("FACT(N)","F") 

defines a function FACT with one formal argument N. Execution of 
FACT is to begin at the label F. No local names are declared. Similarly, 

DEFINE("MATRIXADD(A,B)","MA'7'I,J,K") 

defines a function MATRIXADD with the two formal arguments A 
and B, the entry point MA and local names I, J, and K. 

The total number of formal arguments and local names must not 
exceed ten. This limit is an assembly parameter. 

3.7.2 The Execution of Defined Functions 

The call of a defined function is identical to the call of a primitive 
function (see Section 3.6.1). Hence, trailing arguments which are 
omitted are given null values. A defined function, however, may not be 
called with more arguments than given in its definition. 

When a defined function is called, values of the following names are 
saved : 

(i) the name of the function. 
{ii) all formal arguments. 
{Hi) all local names. 
New values are assigned to these names as follows: 
{i) the name of the function is given a null value. 
{ii) the formal arguments are assigned values by evaluating the 

corresponding arguments in the function call. 
{Hi) all local names are assigned null values. 
Saving of old values and assignment of new values is made from left 
to right as the names appear in the DEFINE call. 

After these new values have been assigned, control is transferred to 
the entry point of the function and program execution continues in a 
normal fashion until transfer is made to one of the two reserved labels 
RETURN or FRETUKN. 

RETURN terminates execution of the function. By convention, the 



928 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

value of the function call is the value of the function name when the 
return was made. For example, if FACT as defined above is designed to 
compute the factorial of a number, the corresponding program might be 

F FACT = .EQ(N,"0") "1" /S(RETURN) 
FACT = FACT(N - "1") * N /(RETURN) 

Then the statements 

SYSPOT = FACT("3") 

SYSPOT = FACT("2") + FACT("4") 

would print 6 and 26, respectively. 

FRETURN terminates execution of the function and signals failure. 
Execution of the statement in which the call occurs terminates at that 
point in the same manner as in the failure of a primitive function. 

When return is made from a function (by either RETURN or 
FRETURN) the saved values of all names are restored in the opposite 
order from which they were saved. 

A function may have a formal argument which is the same as its 
name. This is useful when the value of a function is to be a simple 
modification of one of its arguments. A function whose value is its first 
argument with all occurrences of its second argument deleted might be 
defined as 

DEFINE("DELETE(DELETE,CHAR)","DEL") 

with the program 

DEL DELETE CHAR = /S(DEL)F(RETURN) 

Here DELETE can be operated on as desired and the value has the 
correct name (that is, the name of the function) when the deletion is 
completed. 

3.7.3 Local Names 

Local names may be declared when names used in a function have 
values which should not be destroyed by a function call. Consider the 
following function which intersperses commas between the characters 
in its argument 

COMMA ARG *CHAR/"1"* = /F(RETURN) 

COMMA = COMMA CHAR"," /(COMMA) 

The definition would be 

DEFINE ("COMMA(ARG) ","COMMA'7'CHAR") 



SNOBOL3 929 

so that the use of CHAR during the function call would not change 
the value of CHAR outside the function. 

Local names are particularly important when recursively called 
functions use names for intermediate computation. Appendix II con- 
tains a program in which such use of local names is necessary. 

IV. OPERATING ENVIRONMENT 

The SNOBOL3 system consists of a compiler and an interpreter. The 
compiler translates SNOBOL3 source programs into an internal language 
suitable for the interpreter. 

4.1 Compilation 

4.1.1 Source Program Listing 

During compilation, the source program is read and compiled card 
by card. Only columns 1 through 72 are read by the compiler. Consecu- 
tive statement numbers are added to the listing for reference. 

4.1.2 Comments 

A card with an asterisk in column 1 is treated as a comment. Com- 
ments are printed but otherwise ignored by the compiler. Comments 
may be used freely throughout the program and may be placed any- 
where before the END card. 

4.1.3 Continue Cards 

A statement may be broken over card boundaries by use of the con- 
tinue card convention. A period in column 1 is interpreted by the 
compiler as an indication that the card is a continuation of the preceding 
statement. Statements may be broken over card boundaries anywhere a 
blank is permissible in the syntax. Literals cannot be broken over card 
boundaries. A very long literal must be represented as a concatenation 
of shorter literals. For example, 

SYSPOT = "THE MAXIMUM LENGTH OF " 
"THE COMPUTATIONAL THREAD HAS BEEN " 
"COMPUTED TO BE" 

There is no limit to the number of continue cards which may be used 
for a statement. 



930 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

4.1.4 Compiler Control Cards 

The programmer can perform some operations during the compila- 
tion process by means of compiler control cards. Compiler control cards 
are identified by a minus sign in column 1. The control action is taken 
when the card is encountered. Following the minus sign, the first non- 
blank subfield is taken to be the control word for the card. Other sub- 
fields, if any, are separated internally by commas. The control cards and 
actions are: 

(i) —TITLE 

Eject to a new page in the listing of the source program. 

Title subsequent pages with the information on the remainder 

of the control card. 
(it) —EJECT 

Eject to a new page in the listing of the source program. 
(Hi) —SPACE 

Print a blank line in the source program listing. 
(iv) — UNLIST 

Stop listing the source program. (The source program is 

normally listed.) 
(v) —LIST 

Resume listing. 
(vi) — PCC 

Print control cards. (Control cards are normally not printed.) 

PCC is a binary switch. Successive uses turn printing of 

control cards on and off. 
(vii) —OPEN KEY.FILE 

Open the file in the specified key area. 
(viii) —REWIND FILE 

Rewind the specified file. 
(ix) —SOURCE FILE 

Change the input source for the SNOBOL compiler to the 

specified file. 
(x) —SYSTEM 

Return control to the monitor under which SNOBOL3 

operates, 
(.r?;) — NULLOP OP 

Make the control card operation OP inoperative for the 

rest of the program. 

Invalid control cards, i.e., control cards not in the list above or with a 
format error, are printed but otherwise ignored. Control cards may be 



KNOHOL3 



931 



used anywhere in the program before the END card, including between 
continue cards. 

4.1.5 Diagnostic Messages from the Compiler 

At the end of compilation one of three comments appears: 

(i) SUCCESSFUL COMPILATION, indicating the source pro- 
gram contains no syntactic errors, 

(ii) ERROR IN COMPILATION, indicating syntactic errors 
in the source program, or 

(in) FATAL ERROR ENCOUNTERED DURING COMPILA- 
TION, indicating the occurrence of an error of sufficient 
severity to terminate the compilation process. 

Syntactic errors are printed following the source deck listing with 
statement numbers referring to each type of syntactic error. Compila- 
tion of a statement ceases when a syntactic error is encountered. Conse- 
quently subsequent errors in the same statement will not be detected. 
The syntactic error messages are 

(t) ILLEGAL CONSTRUCTION, usually indicating an illegal 
character in a name, arithmetic operators not surrounded by 
blanks, or arithmetic operations in the pattern not enclosed 
in parentheses. 

(ii) ERROR IN GROUPING, usually indicating unbalanced 

parenthesization, e.g., (A B)) 
(in) TOO MANY ELEMENTS IN FUNCTION OR GROUP- 
ING, indicating overflow of an internal buffer due to an 
excessively complicated parenthetical grouping or function 
call. The maximum number of elements in such structures is 
an assembly parameter of the SNOBOL3 system and is about 
50. 

(iv) VARIABLE WITH GROUPING OR FUNCTION NOT 
CLOSED, indicating that a parenthetical grouping or function 
call in a string variable is not followed by a terminating 
asterisk, e.g., *T/SIZE(N) 
(v) ERROR IN LENGTH SPECIFIER, indicating a syntactic 
error in the length of a fixed-length string variable, e.g., 
*F/"A"* 

(vi) "NAMELESS" STRING REFERENCE IN ASSIGNMENT 
STATEMENT, indicating an attempt to assign a value to a 
literal, function call, or parenthetical grouping, e.g., "3" = "2" 



932 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 1966 

(vii) ARITHMETIC OPERATION WITHOUT SECOND OPER- 
AND, e.g., A = B + /(LI) 

(viii) ARITHMETIC OPERATION WITHOUT FIRST OPER- 
AND, e.g., A = + B 
(ix) TWO ARITHMETIC OPERATIONS IN A ROW, e.g., 

A = B * *C 
(x) NONBINARY ARITHMETIC OPERATION, e.g., A = 

B *C + D 
(xi) PRIOR STATEMENT NOT PROPERLY TERMINATED, 
indicating a missing continue card or incomplete construc- 
tion. This error is not detected until the following card is 
read and determined not to be a continue card. Consequently 
a statement such as A = B + not followed by a continue 
card will cause this error message. Compare with (vii) above. 

(xii) ERROR IN GO-TO FIELD, e.g., /S(L1)(L2) 

(xiii) "NAMELESS" STRING VARIABLE, e.g., 
♦SIZE(SYSPOT)* 

(xiv) ILLEGAL LABEL, indicating a label which does not start 

with a number or letter. 
(aw) MULTIDEFINED LABEL, indicating the same label has 
occurred more than once. 

(xvi) CONTINUE CARD NOT PRECEDED BY STATEMENT, 
indicating the first card in the source deck is a continue card. 
(Comment cards and compiler control cards may be freely 
interspersed between continue cards.) 

If a fatal error occurs during compilation, the nature of the fatal error 
is printed followed by a listing of any syntactic errors. The fatal error 
messages are 

(i) PROGRAM BUFFER OVERFLOW, indicating the source 

program is too large for an internal buffer. The size of this 

buffer is an assembly parameter. 
(ii) ERROR READING INPUT TAPE, indicating a binary 

record was encountered during compilation. This condition 

is almost always due to the omission of an END statement. 
(Hi) END TRANSFER ADDRESS IN ERROR, indicating the 

label specified on the END card does not start with a number 

or letter. 
(iv) END TRANSFER SPECIFIES UNDEFINED LABEL, 

indicating the label specified on the END card does not occur 

as a label in the program. 



SN0B0L3 933 

(y) MORE THAN 50 NONFATAL ERRORS, indicating the 
occurrence of more than 50 syntactic errors in the source 
program. This limit on syntactic errors is an assembly param- 
eter. Such an excess of syntactic errors usually indicates the 
source deck is not a SNOBOL3 program. 

(vi) SYSTEM ERROR, indicating a programming error in the 
SNOBOL3 compiler, or a machine error. 

4.2 Program Execution 

If a fatal error does not occur during compilation, execution is entered. 
Execution continues until the program transfers to or flows into the END 
statement or until an error occurs. 

4.2.1 Error Diagnostics 
The possible errors are: 

(i) ATTEMPT TO EXECUTE STATEMENT WITH COMPI- 
LATION ERROR. Execution is terminated if an attempt is 
made to execute a statement with a compilation error. In 
the case of multidefined labels, the first occurrence is con- 
sidered the valid label, and all transfers to this label go to the 
first occurrence. Subsequent statements with the same label 
are considered to be erroneous and flowing into such a state- 
ment terminates execution. 

(it) ATTEMPT TO TRANSFER TO AN UNDEFINED LABEL. 

(Hi) STRING OVERFLOWED 5461 CHARACTERS. This 
maximum length of strings is an implementation constraint. 

(iv) INTERNAL BUFFER OVERFLOW, indicating an internal 
buffer has been exceeded, usually the result of excessive depth 
of recursive function calls or an excessively long pattern. The 
buffer sizes are assembly parameters. 
(v) ATTEMPT TO USE NEGATIVE LENGTH IN A VARIA- 
BLE, indicating the length of a fixed-length variable is nega- 
tive. 

(vi) FUNCTION FAILED IN GO-TO FIELD, indicating a 

function call failed while evaluating a go-to field. 
(vii) ATTEMPT TO ASSOCIATE A NULL NAME WITH I/O 

FILE. 
(viii) ILLEGAL FILE OR FILE OPERATION, such as perform- 
ing an input or output operation on a name not associated 
with a file or attempting to rewind the standard input file. 



934 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

(ix) ATTEMPT TO READ PAST EOF ON SYSTEM INPUT 
TAPE. The first attempt to read an end-of-file on the standard 
input file results in failure of the statement in which the at- 
tempt occurred. A second attempt is fatal. 
(x) IMPROPER ATTEMPT TO OPSYN A FUNCTION, indi- 
cating an attempt to OPSYN a name to an undefined function. 
(xi) ATTEMPT TO CALL AN UNDEFINED FUNCTION. 
(xii) IMPROPER DEFINITION OF A FUNCTION, indicating 

an error in a call of DEFINE. 
(xiii) UNDEFINED OR NULL LABEL USED IN DEFINE 
STATEMENT, indicating the label specified in a call of 
DEFINE is null or does not occur in the program. 
(xiv) TOO MANY ARGUMENTS IN A FUNCTION DEFINI- 
TION, indicating that the number of arguments and local 
variables in a denned function exceeds ten. 
(xv) IMPROPER CALL OF A DEFINED FUNCTION, indi- 
cating too many arguments in the call of a denned function, 
or an improper argument for the CALL function. 
(xvi) FUNCTION ENTERED OTHER THAN BY CALL, indi- 
cating an attempt to return from a defined function which 
has not been called. 
(xvii) INDIRECT REFERENCE THROUGH THE NULL 
STRING, indicating an attempt to use the null string as a 
name. 
(xviii) OUT OF SPACE, indicating available storage has been 

exhausted. 
(xix) SYSTEM ERROR, indicating a programming error in the 
SNOBOL3 interpreter, or a machine error. 

4.2.2 Post-Mortem Information 

On termination of program execution, information is printed for the 
programmer's use. 

If execution was terminated as the result of an error, the number of 
the statement in which the error occurred and the current level of func- 
tion call are printed in addition to the error message. 

In either normal or error termination, statistics concerning execution 
are provided. The number of statements executed and the number of 
times the scanner was entered for pattern matching are tabulated. 
Storage allocation statistics are provided, and total millisecond times 
in the compiler and interpreter are given. 



SNOBOL3 935 

4.3 Debugging Aids 

Several functions are available specifically for debugging. 

4.3.1 Function Tracing 

Function calls may be traced by use of TRACE (FLIST) where the 
value of FLIST is a list of function names for which a trace is desired. 
For example, the call 

TRACE("SIZE,F,EQUALS") 

results in the subsequent tracing of the three functions given. Both 
primitive and defined functions can be traced. 

When a defined function being traced is called, a message is printed 
on the listing indicating the level from which the call was made, the 
name of the function and the value of all its arguments at the time of 
the call. When the function returns, a message is printed indicating the 
level to which the return is made, the name of the function, and the 
value returned. If a failure return is made, this is also indicated but no 
value is given. 

When a primitive function being traced is called, a message is printed 
on the listing indicating the level at which the call was made, the name 
of the function, and the value of its arguments. If the function call 
returned successfully, the value is given. Otherwise failure is indicated. 

The tracing of functions may be stopped by calling 

STOPTR(FLIST) 

where the value of FLIST is a list of functions for which tracing is to 
be stopped. 

4.3.2 String Tracing 

A name may be traced during execution by calling the function 
STRACE(NAME,FILE) which associates the value of NAME with 
the value of FILE in the trace sense. For example, 

STRACEO'Y'V'OUT") 

would cause Y to be associated with logical file OUT. Subsequently 
every time a value is assigned to Y, a trace message will be printed on 
the associated file indicating the name being traced, its new value and 
the statement number where the value was assigned. STRACE is es- 
sentially an input-output association function and behaves like the other 



936 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 1966 

association functions. Consequently STRACE detaches NAME from 
any other input or output association. Similarly, if the second argument 
is null, association is made with the standard output file. String trac- 
ing may be terminated by detaching NAME. 

4.3.3 Diagnostics Resulting from Tracing 

Two nonfatal errors may occur as a result of tracing. Advisory diag- 
nostic messages are printed for these cases. 

(i) (name) HAS NOT BEEN DEFINED AND WILL NOT BE 
TRACED, indicating a request to trace an undefined function 
of the indicated name, 
(n) ** THE FOLLOWING TRACE OUTPUT HAS BEEN TRUN- 
CATED, indicating that the printing of a string or function 
trace would exceed internal storage limitations, an assembly 
parameter set to about 600 characters. In this case the trace 
printout is truncated. 

4.3.4 String Dumps 

An alphabetical listing of all strings with nonnull values may be 
obtained on termination of execution. The MODE function is used to 
request this string dump. 

MODE("DUMPERR") causes a string dump if execution is termi- 
nated by an error during execution. MODE ("DUMP") causes a string 
dump following either normal or error termination. These calls of the 
MODE function must of course be made before execution is terminated. 

V. ACKNOWLEDGMENT 

The authors wish to express their appreciation to the many people 
who have contributed their ideas to the design of SNOBOL3. D. L. 
Clark, G. F. Faulhaber, G. K. Manacher, M. D. Mcllroy, J. F. Poage, 
A. Simon, L. C. Varian, and D. Walters have been particularly helpful. 

The assistance of G. K. Manacher and L. C. Varian in the implementa- 
tion of the system is most gratefully acknowledged. 

APPENDIX A 

Catalog of Primitive Functions 

Primitive functions may be divided into categories according to the 
nature of their operation and area of applicability. Individual functions 



SN0B0L3 



937 



are described in the appropriate sections. For reference purposes a 
complete list of primitive functions follow. 

A. Numerical Functions (Section 3.2) 

1. .EQ(X,Y) 

2. .NE(X,Y) 

3. .LE(X,Y) 

4. .LT(X,Y) 

5. .GE(X,Y) 

6. .GT(X,Y) 

7. .NUM(X) 

8. .REMDR(X,Y) 

B. Diagnostic Functions (Section 4.3) 

1. TRACE (FLIST) 

2. STOPTR(FLIST) 

3. STRACE(NAME,FILE) 

C. Input-Output and File Manipulation Functions (Section 3.5) 

1. READ(NAME,FILE) 

2. PRINT(NAME,FILE) 

3. PUNCH(NAME,FILE) 

4. EJECT(NAME) 

5. REWIND (NAME) 

6. BSREC(NAME) 

7. DETACH (NAME) 

8. OPEN(KEY,FILE) 

D. System Mode Functions 
1. MODE(X) 

a. "ANCHOR" 



b. "UNANCHOR" 

c. "INTEGER" 

d. "TRUNCATION" 

e. "SYSTEM" 

f. "ENDJOB" 

g. "DUMP" 

h. "DUMPERR" 

2. ANCHOR( ) 

3. UNANCH( ) 

E. Functions Relating to Functions 

1. DEFINE(FORM,LABEL,NAMES) 



Sections 2.8.1 
and 3.3.3 
Section 3.3.3 
Section 3.2.3 
Section 3.2.3 
Section 3.4.4 
Section 3.4.4 
Section 4.3.4 
Section 4.3.4 
Section 3.3.3 
Section 3.3.3 

Sections 2.8.2 
and 3.7 



938 THE BELL SYSTEM TECHNICAL JOURNAL, JULY-AUGUST 1966 

2. OPSYN(NEW,OLD) Section 3.6.2 

3. CALL(FNC) Section 3.6.2 
F. Miscellaneous Functions 

1. EQUALS(X,Y) Sections 2.8.1 

and 3.6.3 

2. UNEQL(X,Y) Section 3.6.3 

3. TRIM(S) Section 3.6.3 

4. TIME( ) Section 3.6.3 

5. DATE( ) Section 3.6.3 

6. SIZE(S) Sections 2.8.1 

and 3.6.3 

7. SYSTEM(FILE) Section 3.4.4 

APPENDIX B 

This appendix contains three sample programs. These programs are 
designed to illustrate various uses and features of SNOBOL3. 

The first two programs involve symbolic evaluations which are in- 
herently recursive. The third is an example of text manipulation. 

All three examples use pattern matching in various forms. Statement 
20 in the first example illustrates the use of back referencing to deter- 
mine whether two lists have an element in common. The second program 
illustrates function tracing. 



SNOBOL3 



939 



EXAMPLE 1. THE WANG ALGBRITHM 

THIS PRBGRAM IS THE ALGBRITHM BY HAB WANG (CF. "TBWARD 
MECHANICAL MATHEMATICS". IBM JBURNAL BF RESEARCH AND 
DEVELBPMENT 41 II JAN. I960 PP. 2-22.) FBR A PRBBF-OEC I S I BN 
PR0CEOURE FBR THE PRBPBS I T I9NAL CALCULUS. IT PRINTS BUT A 
PRBBF BR OISPRBBF ACCBROING AS A GIVEN FBRHULA IS A THEBREM 
BR NBT. THE ALGBRITHM USES SEQUENTS WHICH CBNSIST BF TWB 
LISTS BF FBRMULAS SEPARATED BY AN ARRBW I—*). INITIALLY, FBR 
A GIVEN FBRMULA F THE SEQUENT 



IS FBRMED. WANG HAS DEFINED RULES FAR SIMPLIFYING A FBRMULA 
IN A SEQUENT BY REMBVING THE MAIN CBNNECTIVE ANO THEN 
GENERATING A NEW SEQUENT BR SEQUENTS. THERE IS A TERMINAL 
TEST FBR A SEQUENT CBNSISTING BF BNLY ATBMIC FBRMULAS: 

A SEQUENT CBNSISTING BF BNLY ATBMIC FBRMULAS IS VALID IF 
THE TWB LISTS BF FBRMULAS HAVE A FBRMULA IN CflMMBN. 

BY REPEATED APPLICATIBN BF THE RULES BNE IS LED TB A SET BF 
SEQUENTS CBNSISTING BF ATBMIC FBRMULAS. IF EACH BNE BF THESE 
SEQUENTS IS VALID THEN SB IS THE BRIGINAL FBRMULA. 



OEF INECWANGIANTE.CBNSEOI' 
READ IN THE EXPRESSIBN 



READ 



EXP 
SYSPBT 
SYSPBT 
SYSPBT 
WANG!,* 
SYSPBT 
INVALID SYSPBT 



WANG 



ANBT 
AANO 

A I MP 



TRIMISVSPITI 
"FBRMULA: " EXP 



•WANG", "PHI, PSI") 
/FIEND! 



SYSPBT 

ANTE 

ANTE 

ANTE 

ANTE 

ANTE 

CBNSEQ 
CBNSEQ 
CBNSEQ 
CBNSEO 
CBNSEQ 



EXP) 

■ "VALIO" 

' "NBT VALID" 

• ANTE " --• " 

« NBTI" »IPHI )• 

" ANDI" *IPHII« " 

» IMPI" »(PHI I* " 

" BR(" *(PHI I* ", 

" fcQUI" •IPHI)* " 



/F(INVALID) 
/IREAOI 
/IREADI 
CBNSEQ 
")" = 
,» »IPSII* 
,» •IPSI)« 
• *IPSII* « 
," *IPSII* 



• )» ■ 

• )» = 



NBTI' 
ANDC 
IMP!" 
BRI" 
EQUC 



(ANTE " :" CBNSEQ 
WANGIANTE, CBNSEQ 



•IPHI)» 
»IPHI I* 
•IPHI I* 
•(PHI )• " 
•IPHI )• 

•I ' 



')" = 

'," »(PSI I* ")" ' 
'." *(PS1 !» "I" - 
," »IPSI I* "I" = 
'," *(PSI )» "I" = 



•I PI" 



»• 



WANGIANTE 



WANGIANTE 

WANGIANTE 



PHI I 

» PSI, 



PHI, CBNSEQ) 
PSI, CBNSEQ) 



WANGIANTE " " PSI. CBNSEQ) 
WANGIANTE, CBNSEQ " " PHI ) 



AEqu 


WANGIANTE 
WANGIANTE 


» " PHI 

CBNSEQ " 


" « PSI, CBNSEQ) 
"PHI " " PSI) 


CNBT 


WANGIANTE 


" " PHI 


CBNSEQ) 




CAND 


WANGIANTE 
WANGIANTE 


CBNSEQ " 
CBNSEO " 


" PHI 1 
" PSI) 




C0K 


WANGIANTE 


CBNSEQ " 


■ PHI ■ " 


PSI) 


CI MP 


WANGIANTE 


» « PHI 


CBNSEQ " " 


PSII 


CEQU 

fcND 


WANGIANTE 
WANGIANTE 


" " PHI 
» " PSI 


CBNSEQ " " 
CBNSEQ " " 


PSI) 
PHI) 


SUCCESSFUL 


CBMPILATIBN 









/SIAAND) 
/SIAIMP) 
/SIABR) 
/SIAEQUI 

/SICNBT) 
/SICAND) 

/SIC I MP ) 

/SICBR) 
/S(CEQU) 

** - " P 



/SIRETURNIFIFRETURNI 

/SIRETURNIFIFRETURN) 

/SIRETURNIFIFRETURNI 

/FIFRFTURN) 
/S(RETURN)FIFRETURN) 

/FIFRETURNI 
/S(RETURN)FIFRETURN) 

/FIFRETURNI 
/SIRETURNIFIFRETURNI 

/SIRETURNIFIFRETURNI 

/F(FRETURN) 
/SIRETURNIFIFRETURNI 

/SIRETURNIFIFRETURNI 

/SIRETURNIFIFRETURNI 

/FIFRETURNI 
/SIRETURN)F(FRETURN) 



? 
3 
* 
•> 
6 
T 
H 

10 

11 
12 

13 

1<. 

IS 
16 
17 
1H 
l'( 

20 
20 



940 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 1966 



FBRHULA: INPINBTIBRIP.Q) l.NBTIPII 

— ♦ IMPINBTI0RIP.QII iNBTIPII 
N0TI0RIP.Q) 1 — • N0TIPI 
— • N0TIP) 0RIP.Q) 
P — * BRIP.Q) 
P — • P 
VALID 

FBRMULA: IMPIANOIN0TIP) . N0TIQ) I tEOU(P.O) I 

— • IMP<ANDIN0T(PI,N0TIO)I,EQU(P,Q) I 
ANO(N0T(Pt,N0T(O) I — • EQUIP. 0) 
NBTIPI NBTIO) — • EQUIP, 01 
NBIIOI — * EQUIP. Q> P 
--• EQUIP. 01 P Q 
P — • P Q Q 
Q __• POP 
VALID 

FBRHULA: I HP IIMP(0RIP,Q).0RIP.RI).0RIP. IHPIQ.R))) 

--• IMP(IHP|0RIP,OI,0RIP,RII,0RIP, IHPIO.R) )l 
IHP(0R(P,Q),0RIP»Rlt --• 0RIP.IHPIQ.RI) 
(1HII', HI — • 0R1P.IHPIQ.RI) 
P --* BRIP.IHPIO.RII 
P — * P IMPI0.R1 
P — * P R 
R — * BRIP.IHPIQ.RI) 
R — * P IHPIQ.R) 
R Q — • P R 

--* 0RIP.IHPIO.RH 0RIP.QI 
--• BRIP.O) P IHPIQ.R) 
Q — • BRIP.Q) P R 
Q — • P R P 
VALID 



N0RHAL EXIT FRBH SN0B0L AT LEVEL 

SN0B0L RUN STATISTICS . N0 . BF RULES EXECUTED = 25* N0 0F SCANNER ENTRIES = IB7 

ST0RACE ALL0CAT10N STATISTICS — 171 STRINGS STBRED 397 WBRDS F0R STORED STRINGS 

600 REFERENCE ASSIGNMENT W0ROS . REFERENCE. GARBAGE. AND 

HYPER-GARBAGE C0LLECT I0NI SI 



ELAPSED TIHES-CBHPILER 620 , INTERPRETER 73S IN HS 



SN0B0L3 



941 



EXAMPLE 2. DIFFERENTIATIBN BF ALGEBRAIC EXPRESSI8NS 

THIS PRBGRAM DIFFERENTIATES A FULLY PARENTHESIZED 
ALGEBRAIC EXPRESSIBN WITH RESPECT TB X. THE EXPBNENTI AT IBN 
BPERATBR IS INDICATED BY A DBLLAR SIGN. 

DEFINEI-DIDI". "DO", "U.V.N") I 

DEFINE("S1MPLIFY(EXP)«,"S0","U") 2 

TRACE("D, SIMPLIFY") ' 

READ IN THE EXPRESSIBN. 

EXP = TRIHISYSPIT) /FCENOI * 

MBDE1 "ANCHOR") 5 

SYSPBT = 6 

SYSPBT = "THE DERIVATIVE BF » EXP " IS " S IMPL I F Yl D ( EXP I ) 7 

/(END) 1 

THE FUNCTIBN "D" 

D "I" *(UI* »♦" »IVI* "I" « "I" D1U) "♦" DtV) ")" 8 

/S(RETURN) B 

D "I" »IU)* "-" *IV)» "1" » "I" D(U) "-" OIVI "I" 9 

/SIRETURNI 9 

D "I" »IU1* "»" *(V)« ")" = "II" U "♦" DIV) «)♦!" 10 

V "*" DIU) "II" /SIRETURNI 10 

D "I" »IUI* "/" «(VI* "I" = "IK" V "♦" DIU) "1-1" 11 

U "*" DIV) "ll/l" V "*2)1" /SIRETURNI 11 

«|- »(U)» "»" »IN>* "I" = 12 

«<t« N "•!" U "»" N - "1" ")l»" DIU) ")" 12 

/SIRETURNI 12 

D = EOUALS(D."X«l "1" /S(RETURN) 13 

= »0" /IRETURN) 1* 

THE FUNCTIBN "SIMPLIFY" 



SO HBDEI"UNANCH") 

SI 



S6 



EXP 


"I" »IUI* ««0>" 


EXP 


"I0«" *(U)* ")•' 


EXP 


"I«-*IUI» "*ll" 


EXP 


"1" *IU)* "*ll" 


EXP 


"U*" »IU1* ")" 


EXP 


"10*" »(U>* ")" 


EXP 


"1" *IUI* "*0>" 


EXP 


"(" »(U)* "-01" 


SIMPLIFY 


= EXP 



/St SI > 

/SIS1) 
/SIS2I 
/SI 531 
/SIS*) 
/SIS5I 
/SIS6) 



S7 EX P "(" »IU1* "-01" = U /SIS7) 

/IRETURN) 

END 
SUCCESSFUL CBMPILATI0N 



LEVEL CALL BF 01 " 1 I I A»I X*2 ) ) ♦ I B»X ) 1 *CI" ) 

1 LEVEL CALL BF D( " ( I A* I X*2 ) I ♦! B*X) )") 

2 LEVEL CALL BF Dl "I A*l X$2) I " I 

3 LEVEL CALL BF DI"IX*2I"I 

* LEVEL CALL BF n("X") 

* LEVEL RETURN BF D = "1" 

3 LEVEL RETURN BF D = " I I 2* I X»l ) 1 ♦ 1 ) " 



942 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 1966 



3 LEVEL CALL BF D("A"I 

3 LEVFL RETURN BF = "0" 

2 LEVEL RETURN 0F = »l I A* ( ( 2*1 Xi 1 1 ) *l ! 1*1 (X*ZI»0) I" 

2 LEVEL CALL BF 0("IB*XI") 

LEVEL CALL BF D("X") 

LEVEL RETURN IF = "1" 

LEVEL CALL BF DI"B"I 

LEVEL RETURN BF D = "0" 

LEVEL RETURN 0F D ■= "( (B*l I »(X*OI 1" 

LEVEL RETURN BF D = " ( ( (AMI 2* I X (1 1 I *1 I ) ♦ ( (XS2 1*0) ) + ( ( B«l I K X*OI ) I " 

LEVEL CALL BF DI"C"I 

LEVEL RETURN BF D » "0" 

LEVEL RETURN BF = "( 1 1 1 A*l (2*(X$l J 1*1 1 !♦( (X»2)*0) !♦( (B*1)HX*0I ) 1*01" 

LEVEL CALL BF S IMPLIFYI »( I I (A*l I 2*( X$l I 1*1 1 )»( I X *2 1*01 )H I B»l I *IX*0 I ) I ♦0)' 

LEVEL RETURN BF SIMPLIFY = "I I A*l 2*X ).)+B>" 

THF DERIVATIVE BF I I I A*l XS2I ) ♦( B*X 1 1 *C I IS I I A* I 2*X I I »B I 



N9RNAL EXIT FRBM SNBBBL AT LEVEL 

SNBBBL RUN STATISTICS . NB. BF RULES EXECUTED = 71 NB BF SCANNER ENTRIES - 5* 

SIBRACE ALL0CATI8N STATISTICS — 125 STRINGS STARED 216 MBRDS FBR STBRED STRINGS 

450 REFERENCE ASSIGNMENT MBRDS . REFERENCE. GARBAGEi AND 

HYPER-GARBAGE CBLLECT I0NI SI 

ELAPSED T1MES-CBMPILER »74 , INTERPRETER 3B0 IN MS 



SN0B0L3 



943 



EXAMPLE 3. EDIT8R 

IHIS PRBGRAN RE*OS IN TEXT ANO PRINTS N CHARACTERS 
PER LINE. EXTRA BLANKS ARE INSERTED BETWEEN WBRDS 
13 FILL BUT LINES. 



M8DE("ANCHBR"( 
OEFINE("INSERT(K,LINEI 



READ IN N 
TR1MISYSPIT) 



•IN", "BLANK, WBRD") 



TEXT 

SVSPflT 

SYSPBT 



•N« 

TEXT TRIMISYSPITI ■ " 

"PRINT THE FBLLBWING STRING " N 
" CHARACTERS PER LINE:" 



SYSPBT 

PRINT THE INPUT TEXT 



TEXT 
•SYSPBT/"90"< 
TEXT1 



TEXT1 

TEXT1 

SYSPBT 

SYSPBT 

SYSPBT ■ 

.GTISIZEITEXTI.N) 



TEXT 
SYSPBT 



TEST 
SCAN 
BUMPK 

* FUNCTIflN TS INTERSPERSE K BLANKS IN A LINE 
.EQ!K,»0"1 LINE 



•LINE/IN - Kl« " 

• INSERTIK.LINE) 

• .LTIKiNI K * 



BLINK 
LBBP 



LASTLINE 

ERR 



INSERT 

LINE 

INSERT 

BLANK 

LINE 

INSERT 

K 

INSERT 

LINE 

INSERT 

SYSPBT 
SYSPBT 
SYSPBT 



• • 

■ LINE 

* BLANK » " 
•WBRD* BLANK 

INSERT WBRO BLANK ■ 
.GTIK,"1"I K - "1" 

■ INSFRT LINE 
« INSERT LINE 



/SIREADI 



/S(PRINT) 



/FILASTLINE) 

/F(BUMPK) 

/1TESTI 

/S(SCANIF(ERR) 



/SIRETURNI 

/SIBLINKI 

/(RETURN! 

/FIHBREI 

/S(LBBP) 
/I RETURN) 

/(BLINK) 

/(END) 



END 
SUCCESSFUL CBMPILATIBN 



"•• EOITBR CANNBT PRINT LINE BECAUSE N IS T0B SMALL. 



PRINT THE FBLLBWING STRING 75 CHARACTERS PER LINE: 

TWB FUNCTIBNS HAVE BEEN ADDED TB INCREASE THE FLEXIBILITY BF DEALING WITH THE SYSTEM INPUT 
SBURCE. GETSRC RETURNS AS VALUE THE CURRENT SYSTEM SBURCE. SETSRC SETS THE CURRENT SYSTEM 
SBURCE TB THE VALUE BF FILE. A NULL VALUE IS RETURNED. THREE I/fl FUNCTIBNS HAVE BEEN ADOE 

WHICH TAKE FILES AS ARGUMENTS. THESE FUNCTIBNS CBMPLEMENT THE CBRRESPBNOING SNBBBL3 FUNC 

TUNS WHICH REQUIRE NAMES ASSBCIATED WITH FILES AS ARGUMENTS. 

TW0 FUNCTIBNS HAVE BEEN ADOEO TB INCREASE THE FLEXIBILITY BF DEALING WITH 
THE SYSTEM INPUT SBURCE. GETSRC RETURNS AS VALUE THE CURRENT SYSTEM SBURCE. 
SETSRC SETS THE CURRENT SYSTEM SBURCE TB THE VALUE BF FILE. A NULL VALUE IS 
RETURNED. THREE I/B FUNCTIBNS HAVE BEEN AOOED WHICH TAKE FILES AS 
ARGUMENTS. THESE FUNCTIBNS CBMPLEMENT THE CBRRESPBNOING SNBBBL3 FUNCTIBNS 
WHICH REQUIRE NAMES ASSBCIATED WITH FILES AS ARGUMENTS. 



NBRMAL EXIT FA0M SNBBBL AT LEVEL 

SNBBBL RUN STATISTICS , N0. BF RULES EXECUTEO 



130 NB BF SCANNER ENTRIES 



ST8RAGE ALLBCATIBN STATISTICS ~ 19* STRINGS STBRED 

600 REFERENCE ASSIGNMENT WBRDS . REFERENCE, 

HYPER-GARBAGE CBLLECT I BNI S I 



1296 WBRDS FBR STBREO STRINGS 
GARBAGE, AND 



ELAPSED TIMES-CBMPILER 



INTERPRETER 



944 THE BELL SYSTEM TECHNICAL JOURNAL, JULY -AUGUST 1966 



REFERENCES 

1. Newell, A., Ed., Information Processing Language-V Manual, Prentice-Hall, 

1961. 

2. McCarthy, J., Recursive Functions of Symbolic Expressions and Their Com- 

putation by Machine, Part I. Comm., ACM 3 April, 1960, p. 184. 

3. An Introduction to COMIT Programming, The Research Lab of Electronics 

and the Computation Center, M.I.T., 1961. 

4. Farber, D. J., Griswold, R. E., and Polonsky, I. P., SNOBOL, a String Manip- 

ulation Language, J. ACM, 11, No. 1, 1964. 

5. Manacher, G. K., A Package of Subroutines for the SNOBOL Language. (Un- 

published) 

6. Griswold, R. E. and Polonsky, I. P., Tree Functions for SNOBOL3. (Un- 

published) 

7. Griswold, R. E., Linked-List Functions for SNOBOL3. (Unpublished) 

8. Farber, D. J., Griswold, R. E., Manacher, G. K., Polonsky, I. P., and Varian, 

L. C., Programming Machine-Language Functions for SNOBOL3. (Un- 
published)